package cn.iocoder.yudao.module.member.agency.service;

import cn.iocoder.yudao.framework.business.audit.enums.AuditStatusEnum;
import cn.iocoder.yudao.framework.business.basic.dao.repository.SerialNoRedisRepository;
import cn.iocoder.yudao.framework.business.order.service.AppOrderBaseService;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.member.agency.vo.AgencyOrderVO;
import cn.iocoder.yudao.module.api.pay.bill.enums.BillTypeEnum;
import cn.iocoder.yudao.module.api.pay.order.PayOrderApi;
import cn.iocoder.yudao.module.api.pay.order.dto.PayOrderCreateDTO;
import cn.iocoder.yudao.module.member.agency.dal.dataobject.AgencyApplyDO;
import cn.iocoder.yudao.module.member.agency.dal.dataobject.AgencyOrderDO;
import cn.iocoder.yudao.module.member.agency.dal.dataobject.AgencyPackageDO;
import cn.iocoder.yudao.module.member.agency.dal.mysql.AgencyOrderMapper;
import cn.iocoder.yudao.module.member.agency.dal.mysql.AgencyPackageMapper;
import cn.iocoder.yudao.module.member.agency.mq.AgencyProducer;
import cn.iocoder.yudao.module.member.agency.vo.AgencyOrderSubmitDTO;
import cn.iocoder.yudao.module.member.agency.vo.AppAgencyOrderVO;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.Objects;

import static cn.iocoder.yudao.module.api.member.ConfigConstants.AGENCY_ORDER_NO_PREFIX;

/**
 * 招商人员身份订单 Service 实现类
 *
 * @author 山野羡民
 */
@Slf4j
@Service
@Validated
public class AppAgencyOrderServiceImpl extends AppOrderBaseService<AgencyOrderDO, AppAgencyOrderVO, AgencyOrderSubmitDTO> implements AppAgencyOrderService {
    @Resource
    private AgencyOrderMapper agencyOrderMapper;
    @Resource
    private AgencyPackageMapper agencyPackageMapper;

    @Resource
    private AgencyApplyService agencyApplyService;
    @Resource
    private AppAgencyUserService appAgencyUserService;

    @Resource
    private SerialNoRedisRepository serialNoRedisRepository;
    @Resource
    private AgencyProducer agencyProducer;

    @Resource
    private PayOrderApi payOrderApi;

    @Override
    protected AgencyOrderMapper getInjectedMapper() {
        return agencyOrderMapper;
    }

    @Nonnull
    @Override
    protected AgencyOrderDO onOrderCreateBefore(@Nonnull AgencyOrderSubmitDTO reqVO, @Nonnull Long userId) {
        AgencyApplyDO applyDO = agencyApplyService.getDetailByUserId(userId, null);
        Assertions.notNull(applyDO, "招商人员申请资料不存在");
        Assertions.isTrue(Objects.equals(applyDO.getAuditStatus(), AuditStatusEnum.PASS.getValue()), "招商人员申请资料还未审核通过");
        // 校验招商人员缴费套餐存在
        AgencyPackageDO packageDO = agencyPackageMapper.selectById(reqVO.getPackageId());
        Assertions.notNull(packageDO, "招商人员缴费套餐不存在");
        Assertions.equals(packageDO.getLevel(), applyDO.getLevel(), "招商人员缴费套餐无效");
        // 构建订单信息
        AgencyOrderDO order = new AgencyOrderDO();
        order.setUserId(userId);
        order.setPackageId(packageDO.getId());
        order.setLevel(packageDO.getLevel());
        order.setDays(packageDO.getDays());
        order.setPrice(packageDO.getPrice());
        order.setSnapshot(JsonUtils.toJsonString(packageDO));
        order.setTradeNo(serialNoRedisRepository.generateNo(AGENCY_ORDER_NO_PREFIX));
        order.setNote("购买招商人员身份套餐【%s】".formatted(packageDO.getName()));
        return order;
    }

    @Async
    @Override
    public void createPayOrder(@Nonnull AgencyOrderDO order) {
        PayOrderCreateDTO createDTO = new PayOrderCreateDTO();
        createDTO.setTradeNo(order.getTradeNo());
        createDTO.setSubject(BillTypeEnum.PAY_AGENCY.getName());
        createDTO.setBody(order.getNote());
        createDTO.setPrice(order.getPrice());
        payOrderApi.createOrder(createDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    protected void onPaidAfter(AgencyOrderDO order) {
        agencyApplyService.updateWhenPaid(order.getTradeNo(), order.getUserId(), order.getPackageId());
        appAgencyUserService.updateWhenPaid(order);
        agencyProducer.sendAgencyOrderPaidMessage(BeanUtils.toBean(order, AgencyOrderVO.class));
    }

}